import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BillManager {
    private List<BillRecord> records = new ArrayList<>();
    private Map<String, Double> monthlyBudget = new HashMap<>();  // 存储每月预算，格式："yyyy-MM" -> 预算金额

    // 记录收入
    public void recordIncome(Date date, double amount, String category, String note) {
        if (amount <= 0) {
            throw new IllegalArgumentException("收入金额必须为正数");
        }
        BillRecord incomeRecord = new BillRecord(date, amount, category, note);
        records.add(incomeRecord);
    }

    // 记录支出
    public void recordExpense(Date date, double amount, String category, String note) {
        if (amount <= 0) {
            throw new IllegalArgumentException("支出金额必须为正数");
        }
        BillRecord expenseRecord = new BillRecord(date, -amount, category, note);
        records.add(expenseRecord);
    }

    // 设置每月预算
    public void setMonthlyBudget(String month, double budget) {
        if (budget < 0) {
            throw new IllegalArgumentException("预算金额不能为负数");
        }
        monthlyBudget.put(month, budget);
    }

    // 获取当前月剩余可用预算
    public double getRemainingBudget(String month) {
        double budget = monthlyBudget.getOrDefault(month, 0.0);
        double totalExpense = calculateTotalExpenseForMonth(month);
        return budget - totalExpense;
    }

    // 展示所有账单记录（收入和支出分开显示）
    public void displayBills() {
        System.out.println("收入记录：");
        displayIncomeBills();
        System.out.println("支出记录：");
        displayExpenseBills();
    }

    // 展示收入账单记录
    private void displayIncomeBills() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        for (BillRecord record : records) {
            if (record.getAmount() > 0) {
                System.out.println("日期：" + dateFormat.format(record.getDate()) +
                        ", 金额：" + record.getAmount() +
                        ", 类别：" + record.getCategory() +
                        ", 备注：" + record.getNote());
            }
        }
    }

    // 展示支出账单记录
    private void displayExpenseBills() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        for (BillRecord record : records) {
            if (record.getAmount() < 0) {
                System.out.println("日期：" + dateFormat.format(record.getDate()) +
                        ", 金额：" + Math.abs(record.getAmount()) +
                        ", 类别：" + record.getCategory() +
                        ", 备注：" + record.getNote());
            }
        }
    }

    // 按指定日期查询收入账单记录
    public List<BillRecord> queryIncomeByDate(Date date) {
        List<BillRecord> result = new ArrayList<>();
        for (BillRecord record : records) {
            if (record.getAmount() > 0 && record.getDate().equals(date)) {
                result.add(record);
            }
        }
        return result;
    }

    // 按指定日期查询支出账单记录
    public List<BillRecord> queryExpenseByDate(Date date) {
        List<BillRecord> result = new ArrayList<>();
        for (BillRecord record : records) {
            if (record.getAmount() < 0 && record.getDate().equals(date)) {
                result.add(record);
            }
        }
        return result;
    }

    // 按日期范围查询收入账单记录
    public List<BillRecord> queryIncomeByDateRange(Date startDate, Date endDate) {
        List<BillRecord> result = new ArrayList<>();
        for (BillRecord record : records) {
            if (record.getAmount() > 0 && record.getDate().compareTo(startDate) >= 0 && record.getDate().compareTo(endDate) <= 0) {
                result.add(record);
            }
        }
        return result;
    }

    // 按日期范围查询支出账单记录
    public List<BillRecord> queryExpenseByDateRange(Date startDate, Date endDate) {
        List<BillRecord> result = new ArrayList<>();
        for (BillRecord record : records) {
            if (record.getAmount() < 0 && record.getDate().compareTo(startDate) >= 0 && record.getDate().compareTo(endDate) <= 0) {
                result.add(record);
            }
        }
        return result;
    }

    // 按类别查询收入账单记录
    public List<BillRecord> queryIncomeByCategory(String category) {
        List<BillRecord> result = new ArrayList<>();
        for (BillRecord record : records) {
            if (record.getAmount() > 0 && record.getCategory().equals(category)) {
                result.add(record);
            }
        }
        return result;
    }

    // 按类别查询支出账单记录
    public List<BillRecord> queryExpenseByCategory(String category) {
        List<BillRecord> result = new ArrayList<>();
        for (BillRecord record : records) {
            if (record.getAmount() < 0 && record.getCategory().equals(category)) {
                result.add(record);
            }
        }
        return result;
    }

    // 计算每月总收入
    public double calculateTotalIncomeForMonth(String month) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
        double totalIncome = 0;
        for (BillRecord record : records) {
            if (record.getAmount() > 0 && dateFormat.format(record.getDate()).equals(month)) {
                totalIncome += record.getAmount();
            }
        }
        return totalIncome;
    }

    // 计算每月总支出
    public double calculateTotalExpenseForMonth(String month) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
        double totalExpense = 0;
        for (BillRecord record : records) {
            if (record.getAmount() < 0 && dateFormat.format(record.getDate()).equals(month)) {
                totalExpense += Math.abs(record.getAmount());
            }
        }
        return totalExpense;
    }

    // 计算每月各类别金额（收入和支出分开）
    public Map<String, Double> calculateCategoryAmountsForMonth(String month) {
        Map<String, Double> categoryAmounts = new HashMap<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
        for (BillRecord record : records) {
            String key = dateFormat.format(record.getDate()) + "-" + record.getCategory();
            if (dateFormat.format(record.getDate()).equals(month)) {
                categoryAmounts.put(key, categoryAmounts.getOrDefault(key, 0.0) + record.getAmount());
            }
        }
        return categoryAmounts;
    }
}